/**
 定义用户自定义类型,类型的每个字段都必须是已定义的且最终都是 GraphQL 中定义的类型。
 定义根类型,每种根类型中包含了准备暴露给服务调用方的用户自定义类型
 定义 Schema,每一个 Schema 中允许出现三种根类型：query，mutation，subscription，其中至少要有 query
 */
const graphql = require('graphql');
const {CategoryModel, ProductModel} = require('./model');
const {GraphQLObjectType,GraphQLString,GraphQLSchema,GraphQLNonNull,GraphQLList} = graphql;

const categories = [
  {id: '1', name: '图书', xxx:'yyy'/** ←没有在定义的数据结构中的字段 不会被返回*/},
  {id: '2', name: '数码'},
  {id: '3', name: '食品'}
];

const products = [
  {id: "1", name: '红楼梦', category: '1'}
  ,{id: "2", name: '西游记', category: '1'}
  ,{id: "3", name: '三国演义', category: '1'}
  ,{id: "4", name: '水浒传', category: '1'}
  ,{id: "5", name: 'iPhone', category: '2'}
  ,{id: "6", name: '面包', category: '3'}
];

/** 定义用户自定义类型,类型的每个字段都必须是已定义的且最终都是 GraphQL 中定义的类型。*/
/** 就是定义数据结构，返回和查询的数据结构都被这里所约束 */
//先定义产品类别类型
const Category = new GraphQLObjectType({
  name: 'Category',
  fields: () => ({
    id: {type: GraphQLString}
    , name: {type: GraphQLString}
    , products: {
      type: new GraphQLList(Product),
      resolve(parent) {
        // return products.filter(item => item.category === parent.id)
        return ProductModel.find({category: parent.id});
      }
    }
  })
});

const Product = new GraphQLObjectType({
  name: 'Product',
  fields: () => ({
    id: {type: GraphQLString}
    , name: {type: GraphQLString}
    , category: { // 字符串转成对象 1 => {name:'图片'}
      type: Category,
      resolve/*resolve,解析的意思*/(parent/** ←这里指的就是Product表示的一条产品数据*/) {
        // return categories.find(item => item.id === parent.category);
        return CategoryModel.findById(parent.category);
      }
    }
  })
});


/** 定义根类型,每种根类型中包含了准备暴露给服务调用方的用户自定义类型*/
/** 定义查询如何返回,还能在这里定义一些必填参数(用于resolve)*/
const RootQuery = new GraphQLObjectType({
  name: 'RootQuery',
  fields: {
    getCategory: { // 根据分类的ID查询单个分类
      type: Category,
      args: {
        // id: {type: GraphQLString}
        id: {type: new GraphQLNonNull(GraphQLString)} /** 用GraphQLNonNull包裹后此参数就会成为必填参数*/
      },
      resolve(parent, args) {
        // return categories.find((item) => item.id === args.id);
        return CategoryModel.findById(args.id);
      }
    },
    getCategories: {
      type: new GraphQLList(Category),
      args: {},
      resolve(parent, args) {
        // return categories;
        return CategoryModel.find();
      }
    },
    getProduct: { // 根据分类的ID查询单个产品
      type: Product,
      args: {
        id: {type: new GraphQLNonNull(GraphQLString)}
      },
      resolve(parent, args){
        // return products.find(item => item.id === args.id);
        return ProductModel.findById(args.id);
      }
    },
    getProducts: { // 根据分类的ID查询单个产品
      type: new GraphQLList(Product),
      args: {},
      resolve(parent, args){
        // return products;
        return ProductModel.find();
      }
    }
  }
});

const RootMutation = new GraphQLObjectType({
  name: 'RootMutation',
  fields: {
    addCategory:{
      type: Category
      ,args: {
        name: {type: new GraphQLNonNull(GraphQLString)}
      }
      ,resolve(parent,args){
        /*args.id = categories.length + 1;
        categories.push(args);
        return args;*/

        return CategoryModel.create(args);
      }
    },
    addProduct:{
      type: Product
      ,args: {
        name: {type: new GraphQLNonNull(GraphQLString)}
        ,category: {type: new GraphQLNonNull(GraphQLString)}
      }
      ,resolve(parent,args){
        /*args.id = products.length + 1;
        categories.push(args);
        return args;*/

        return ProductModel.create(args);
      }
    }
  }
});

/** 定义Schema */
module.exports = new GraphQLSchema({
  query: RootQuery,
  mutation: RootMutation
});
